import { Platform } from '@angular/cdk/platform';
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  Input,
  OnChanges, Renderer2,
  SimpleChanges,
  ViewChild, ViewEncapsulation,
} from '@angular/core';
import { ApesSizeMap, ApesUpdateHostClassService } from '@shared/apes/core';



export type ApesAvatarShape = 'square' | 'circle';
export type ApesAvatarSize = 'small' | 'large' | 'default';

export interface ApesAvatarSizeMap {
  [size: string]: string;
}

@Component({
  selector           : 'apes-avatar',
  templateUrl        : './apes-avatar.component.html',
  providers          : [ ApesUpdateHostClassService ],
  preserveWhitespaces: false,
  changeDetection    : ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None
})
export class ApesAvatarComponent implements OnChanges {
  @Input() apesShape: ApesAvatarShape = 'circle';
  @Input() apesSize: ApesAvatarSize = 'default';
  @Input() apesText: string;
  @Input() apesSrc: string;
  @Input() apesSrcSet: string;
  @Input() apesAlt: string;
  @Input() apesIcon: string;

  oldAPIIcon = true;
  hasText: boolean = false;
  hasSrc: boolean = true;
  hasIcon: boolean = false;
  textStyles: {};

  @ViewChild('textEl',{static:false}) textEl: ElementRef;

  private el: HTMLElement = this.elementRef.nativeElement;
  private prefixCls = 'apes-avatar';
  private sizeMap: ApesSizeMap = { large: 'lg', small: 'sm' };

  constructor(private elementRef: ElementRef,
              private cd: ChangeDetectorRef,
              private updateHostClassService: ApesUpdateHostClassService,
              private renderer: Renderer2,
              private platform: Platform){
  }

  setClass(): this {
    const classMap = {
      [ this.prefixCls ]                                    : true,
      [ `${this.prefixCls}-${this.sizeMap[ this.apesSize ]}` ]: this.sizeMap[ this.apesSize ],
      [ `${this.prefixCls}-${this.apesShape}` ]               : this.apesShape,
      [ `${this.prefixCls}-icon` ]                          : this.apesIcon,
      [ `${this.prefixCls}-image` ]                         : this.hasSrc
    };
    this.updateHostClassService.updateHostClass(this.el, classMap);
    this.cd.detectChanges();
    return this;
  }

  imgError(): void {
    this.hasSrc = false;
    this.hasIcon = false;
    this.hasText = false;
    if (this.apesIcon) {
      this.hasIcon = true;
    } else if (this.apesText) {
      this.hasText = true;
    }
    this.setClass().notifyCalc();
    this.setSizeStyle();
  }
  ngOnChanges(changes: SimpleChanges): void {
    if (changes.hasOwnProperty('apesIcon') && changes.apesIcon.currentValue) {
      this.oldAPIIcon = changes.apesIcon.currentValue.indexOf('anticon') > -1;
    }
    this.hasText = !this.apesSrc && !!this.apesText;
    this.hasIcon = !this.apesSrc && !!this.apesIcon;
    this.hasSrc = !!this.apesSrc;

    this.setClass().notifyCalc();
    this.setSizeStyle();
  }
  private calcStringSize(): void {
    if (!this.hasText) {
      return;
    }

    const childrenWidth = this.textEl.nativeElement.offsetWidth;
    const avatarWidth = this.el.getBoundingClientRect().width;
    const scale = avatarWidth - 8 < childrenWidth ? (avatarWidth - 8) / childrenWidth : 1;
    this.textStyles = {
      transform: `scale(${scale}) translateX(-50%)`
    };
    if (typeof this.apesSize === 'number') {
      Object.assign(this.textStyles, {
        lineHeight: `${this.apesSize}px`
      });
    }
    this.cd.detectChanges();
  }

  private notifyCalc(): this {
    // If use ngAfterViewChecked, always demands more computations, so......
    setTimeout(() => {
      this.calcStringSize();
    });
    return this;
  }

  private setSizeStyle(): void {
    const size = typeof this.apesSize === 'string' ? this.apesSize : `${this.apesSize}px`;
    this.renderer.setStyle(this.el, 'width', size);
    this.renderer.setStyle(this.el, 'height', size);
    this.renderer.setStyle(this.el, 'line-height', size);
    if (this.hasIcon) {
      this.renderer.setStyle(this.el, 'font-size', `calc(${size} / 2)`);
    }
  }
}
